package com.qen.common;

import cn.hutool.core.util.StrUtil;
import com.qen.annotation.LogicDel;
import com.qen.enums.SqlKeyword;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 逻辑删除信息类
 *
 * @author licz
 * @since 1.0.0
 */
public class LogicInfoUtils {

    private static final Map<Class<?>, Map<String, String>> LOGIC_CACHE = new ConcurrentHashMap<>();

    private static final Map<Class<?>, Map<String, String>> LOGIC_CACHE_NO_AND = new ConcurrentHashMap<>();

    private static final Map<Class<?>, Map<String, String>> LOGIC_CACHE_INVERT = new ConcurrentHashMap<>();

    public static String getLogicInfo(Integer tableIndex, Class<?> clazz, boolean hasAlias, String alias) {
        Map<String, String> absent = LOGIC_CACHE.computeIfAbsent(clazz, k -> new ConcurrentHashMap<>());
        return absent.computeIfAbsent(hasAlias ? alias : (alias + tableIndex), key -> getLogicStr(key, clazz, true, false));
    }

    public static String getLogicInfoApt(Class<?> clazz, String alias) {
        Map<String, String> absent = LOGIC_CACHE.computeIfAbsent(clazz, k -> new ConcurrentHashMap<>());
        return absent.computeIfAbsent(alias, key -> getLogicStr(key, clazz, true, false));
    }

    public static String getLogicInfoNoAnd(Integer tableIndex, Class<?> clazz, boolean hasAlias, String alias) {
        Map<String, String> absent = LOGIC_CACHE_NO_AND.computeIfAbsent(clazz, k -> new ConcurrentHashMap<>());
        return absent.computeIfAbsent(hasAlias ? alias : (alias + tableIndex), key -> getLogicStr(key, clazz, false, false));
    }

    public static String getLogicInfoInvert(Integer tableIndex, Class<?> clazz, boolean hasAlias, String alias) {
        Map<String, String> absent = LOGIC_CACHE_INVERT.computeIfAbsent(clazz, k -> new ConcurrentHashMap<>());
        return absent.computeIfAbsent(hasAlias ? alias : (alias + tableIndex), key -> getLogicStr(key, clazz, false, true));
    }

    private static String getLogicStr(String prefix, Class<?> clazz, boolean and, boolean invert) {
        String logicStr;
//        TableDesc tableInfo = TableInfoHelper.getTableInfo(clazz);
        Field field = getFieldByPojo(clazz);
        if (field != null) {
            LogicDel logicDel = field.getAnnotation(LogicDel.class);
            final String notDeleteValue = logicDel.normalStatus();
//            logicField.getLogicNotDeleteValue();
            final String deleteValue = logicDel.deleteStatus();
//                    logicField.getLogicDeleteValue();
            String col = BeetlUtils.getSQLManager().getNc().getColName(clazz, field.getName());
            logicStr = (and ? (StrUtil.SPACE + SqlKeyword.AND.getSqlSegment() + StrUtil.SPACE) : StrUtil.EMPTY)
                    + prefix + StrUtil.DOT + col + (invert ? notDeleteValue : deleteValue);
        } else {
            logicStr = StrUtil.EMPTY;
        }
        return logicStr;
    }

    /**
     * 获取POJO设置的逻辑删除字段
     *
     * @param clz
     * @return
     */
    public static Field getFieldByPojo(Class<?> clz) {
        for (Field field : clz.getDeclaredFields()) {
            if (field.isAnnotationPresent(LogicDel.class)) {
                return field;
            }
        }
        return null;
    }

}
